package cn.b.sky.form.service.impl;

import cn.b.sky.form.dao.CustomQueryDao;
import cn.b.sky.form.enums.QueryDataType;
import cn.b.sky.form.enums.QueryOperatorEnum;
import cn.b.sky.form.enums.TableTypeEnum;
import cn.b.sky.form.enums.TimeUnit;
import cn.b.sky.form.model.BusinessType;
import cn.b.sky.form.model.QueryFieldCondition;
import cn.b.sky.form.model.QueryScreen;
import cn.b.sky.form.service.BusinessTypeService;
import cn.b.sky.form.service.CustomQueryService;
import cn.b.sky.user.SecurityContextUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 
 * <strong>Title : CustomQueryServiceImpl.java<br></strong>
 * <strong>Package : cn.b.sky.form.service.impl<br></strong>
 * <strong>Description : </strong>自定义查询业务实现类<br> 
 * <strong>Create on : 2016年11月23日 下午6:16:56<br></strong>
 * <p>
 * @author dapeng.li<br>
 * @version <strong>v1.0.0</strong><br>
 * <br>
 * <strong>修改历史:</strong><br>
 * 修改人|修改日期|修改描述<br>
 * -------------------------------------------<br>
 * <br>
 * <br>
 */
@Service("customQueryService")
public class CustomQueryServiceImpl implements CustomQueryService {

  private String dataBaseType = "mysql";

  @Resource
  CustomQueryDao customQueryDao;

  @Resource
  BusinessTypeService businessTypeService;

  @Override
  public Map<String, Object> queryRows(String tableName, String selectFields, List<QueryFieldCondition> whereConditions,
      String orderBy, int startRow, int pageSize) {
    Map<String, Object> result = new HashMap<String, Object>();
    String whereSql = getWhereSql(whereConditions);
    List<Map<String, Object>> data = customQueryDao.queryRows(tableName, selectFields, whereSql, orderBy, startRow,
        pageSize);
    int count = customQueryDao.getRowsCount(tableName, whereSql);
    result.put("data", data);
    result.put("count", count);
    return result;
  }

  private String getWhereSql(List<QueryFieldCondition> whereConditions) {
    String whereSql = "";
    for (QueryFieldCondition queryField : whereConditions) {
      if (QueryDataType.STRING.getValue().equals(queryField.getDataType())
          || QueryDataType.TEXT.getValue().equals(queryField.getDataType())) {
        //字符串和文本类型
        if (QueryOperatorEnum.CT.getValue().equals(queryField.getOperator())) {
          if (!StringUtils.isBlank(queryField.getFieldValue())) {
            whereSql += "and " + queryField.getFieldName() + " like '%" + queryField.getFieldValue() + "%' ";
          }
        } else if (QueryOperatorEnum.EQ.getValue().equals(queryField.getOperator())) {
          if (!StringUtils.isBlank(queryField.getFieldValue())) {
            whereSql += "and " + queryField.getFieldName() + "='" + queryField.getFieldValue() + "' ";
          }
        } else if (QueryOperatorEnum.BT.getValue().equals(queryField.getOperator())) {
          if (!StringUtils.isBlank(queryField.getStartValue())) {
            whereSql += "and " + queryField.getFieldName() + ">='" + queryField.getStartValue() + "' ";
          }
          if (!StringUtils.isBlank(queryField.getEndValue())) {
            whereSql += "and " + queryField.getFieldName() + "<='" + queryField.getEndValue() + "' ";
          }
        } else if (QueryOperatorEnum.IN.getValue().equals(queryField.getOperator())) {
          if (queryField.getFieldValues() != null && queryField.getFieldValues().length > 0) {
            String[] values = new String[queryField.getFieldValues().length];
            for (int i = 0; i < queryField.getFieldValues().length; i++) {
              String value = queryField.getFieldValues()[i];
              if ("#CURRENTUSER".equals(value)) {
                value = "'" + SecurityContextUtil.getCurrentUserName() + "'";
              } else {
                value = "'" + value + "'";
              }
              values[i] = value;
            }
            whereSql += "and " + queryField.getFieldName() + " in (" + StringUtils.join(values, ",") + ") ";
          }

        }
      } else if (QueryDataType.LONG.getValue().equals(queryField.getDataType())
          || QueryDataType.NUMBER.getValue().equals(queryField.getDataType())) {
        //数值类型
        if (QueryOperatorEnum.EQ.getValue().equals(queryField.getOperator())) {
          if (!StringUtils.isBlank(queryField.getFieldValue())) {
            whereSql += "and " + queryField.getFieldName() + "=" + queryField.getFieldValue() + " ";
          }
        } else if (QueryOperatorEnum.BT.getValue().equals(queryField.getOperator())) {
          if (!StringUtils.isBlank(queryField.getStartValue())) {
            whereSql += "and " + queryField.getFieldName() + ">=" + queryField.getStartValue() + " ";
          }
          if (!StringUtils.isBlank(queryField.getEndValue())) {
            whereSql += "and " + queryField.getFieldName() + "<=" + queryField.getEndValue() + " ";
          }
        }
      } else if (QueryDataType.STATICOPTION.getValue().equals(queryField.getDataType())
          || QueryDataType.DYNAMICOPTION.getValue().equals(queryField.getDataType())) {
        //枚举类型
        if (!StringUtils.isBlank(queryField.getFieldValue())) {
          whereSql += "and " + queryField.getFieldName() + "='" + queryField.getFieldValue() + "' ";
        }
      } else if (QueryDataType.DATE.getValue().equals(queryField.getDataType())
          || QueryDataType.DATETIME.getValue().equals(queryField.getDataType())) {
        //日期类型
        if (QueryOperatorEnum.SC.getValue().equals(queryField.getOperator())) {
          if (!StringUtils.isBlank(queryField.getFieldValue())) {
            double delayDays = 0;
            if (TimeUnit.DAY.getValue().equals(queryField.getTimeUnit())) {
              delayDays = Integer.parseInt(queryField.getFieldValue());
            } else if (TimeUnit.HOUR.getValue().equals(queryField.getTimeUnit())) {
              delayDays = Integer.parseInt(queryField.getFieldValue()) / 24.0D;
            } else if (TimeUnit.MINUTE.getValue().equals(queryField.getTimeUnit())) {
              delayDays = Integer.parseInt(queryField.getFieldValue()) / 24.0D / 60.0D;
            }
            if (TableTypeEnum.ORACLE.getCode().equals(dataBaseType.toUpperCase())) {
              whereSql += "and " + queryField.getFieldName() + ">=sysdate-" + delayDays + " ";
            } else if (TableTypeEnum.MYSQL.getCode().equals(dataBaseType.toUpperCase())) {
              whereSql += "and " + queryField.getFieldName() + ">=date_add(now(),interval -" + delayDays + " day) ";
            }
          }
        } else if (QueryOperatorEnum.BT.getValue().equals(queryField.getOperator())) {
          if (!StringUtils.isBlank(queryField.getStartValue())) {
            if (TableTypeEnum.ORACLE.getCode().equals(dataBaseType.toUpperCase())) {
              whereSql += "and " + queryField.getFieldName() + ">=to_date('" + queryField.getStartValue()
                  + "', 'yyyy-mm-dd')";
            } else if (TableTypeEnum.MYSQL.getCode().equals(dataBaseType.toUpperCase())) {
              whereSql += "and " + queryField.getFieldName() + ">=STR_TO_DATE('" + queryField.getStartValue()
                  + "', '%Y-%m-%d') ";
            }
          }
          if (!StringUtils.isBlank(queryField.getEndValue())) {
            if (TableTypeEnum.ORACLE.getCode().equals(dataBaseType.toUpperCase())) {
              whereSql += "and " + queryField.getFieldName() + "<to_date('" + queryField.getEndValue()
                  + "', 'yyyy-mm-dd')+1";
            } else if (TableTypeEnum.MYSQL.getCode().equals(dataBaseType.toUpperCase())) {
              whereSql += "and " + queryField.getFieldName() + "<STR_TO_DATE('" + queryField.getEndValue()
                  + "', '%Y-%m-%d')+1";
            }
          }
        }
      }
    }
    return whereSql;
  }

  @Override
  public QueryScreen selectQueryScreen(String siteCode, String businessType, String screenName, String createUser) {
    return customQueryDao.selectQueryScreen(siteCode, businessType, screenName, createUser);
  }

  @Override
  public void updateQueryScreen(QueryScreen queryScreen) {
    customQueryDao.updateQueryScreen(queryScreen);
  }

  @Override
  public List<BusinessType> getQueryTree(String siteCode, String createUser) {
    List<BusinessType> types = businessTypeService.selectBusinessTypes();
    if (types != null && types.size() > 0) {
      for (BusinessType type : types) {
        List<QueryScreen> querys = new ArrayList<QueryScreen>();
        List<QueryScreen> currentOwner = customQueryDao.selectQueryScreenByBusinessType(siteCode,
            type.getBusinessType(), createUser, false);
        if (currentOwner != null) {
          querys.addAll(currentOwner);
        }
        List<QueryScreen> otherOwner = customQueryDao.selectQueryScreenByBusinessType(siteCode, type.getBusinessType(),
            createUser, true);
        if (otherOwner != null) {
          querys.addAll(otherOwner);
        }
        type.setQuerys(querys);
      }
    }
    return types;
  }

  @Override
  public void insertQueryScreen(QueryScreen queryScreen) {
    customQueryDao.insertQueryScreen(queryScreen);
  }

  @Override
  public void updateQueryScreenName(QueryScreen queryScreen) {
    customQueryDao.updateQueryScreenName(queryScreen);
  }

  @Override
  public void deleteQueryScreen(String siteCode, String businessType, String screenName, String createUser) {
    customQueryDao.deleteQueryScreen(siteCode, businessType, screenName, createUser);
  }

  @Override
  public int getRowsCount(String tableName, List<QueryFieldCondition> whereConditions) {
    String whereSql = getWhereSql(whereConditions);
    return customQueryDao.getRowsCount(tableName, whereSql);
  }

}
